﻿jQuery.extend(jQuery.prototype, {
    SearchSelect: function (settings) {
        var thisobj = this; 	//当前对象
        var id = thisobj.attr("id");
        var height = thisobj.height(); 	//当前对象的高度
        var paddingLeft = parseInt(thisobj.css("paddingLeft").replace("px", ""));
        var paddingRight = parseInt(thisobj.css("paddingRight").replace("px", ""));
        var width = thisobj.width() + paddingLeft + paddingRight + 2; 	//当前对象的宽度

        var options = jQuery.extend({
            data: [], 	//数据
            ulwidth: 0, //定义浮层宽度,默认最小宽度为文本框宽度，随内容自动增宽
            btnwidth: 0, //定义右边按钮的宽度
            liStrlen: 0, //定义截取字体的长度，默认不截字
            ulmaxheight: 332, //定义浮层的最大高度，默认220像素
            liHeight: 24, //定义LI的高度，默认22像素
            groupHeight: 24, //定义optgroup的高度，默认24像素
            groupLineHeight: 24, //定义optgroup的行高，默认24像素
            selectBtnId: "selectBtnDiv",
            defaultText: "请选择...", //定义文本框的初始值，也就是未选中的值
            defaultVal: "",
            selectFirst: false, //是否选中第一个LI，默认不选中
            onChange: function (val) { } //onChange事件，由调用者覆盖,默认不做任何处理,第一个参数为更改的值
        }, settings);


        //是否截取字符
        var textTruncation = function (text) {
            if (options.liStrlen != 0) {
                return SetStrLength(text, options.liStrlen) + '...';
            }
            return text;
        }

        var init = function () {
            $("#" + id).val(options.defaultText);
            $("#" + id).attr("title", options.defaultText);

            if (options.data.length <= 0) return;
            var leftpx = thisobj.get(0).offsetLeft; //当前对象的距离左边距离
            var toppx = thisobj.get(0).offsetTop; 	//当前对象的距离顶部距离

            var ulwidth = 'min-width:' + (width - 2 + options.btnwidth) + 'px;';
            if (options.ulwidth != 0) {
                ulwidth = 'width:' + options.ulwidth + 'px;';
            }
            var html = '<ul class="searchSelect-UL" id="searchSelect-UL-' + id + '" style="' + ulwidth + ' max-height:' + options.ulmaxheight + 'px;"></ul><input type="hidden" id="searchSelect-hidden-' + id + '">';
            $("body").append(html);

            if (options.defaultVal != "" && options.defaultVal != null) {
                for (var i = 0, l = options.data.length; i < l; ++i) {
                    for (var j = 0, len = options.data[i].data.length; j < len; ++j) {
                        if (options.data[i].data[j][0] == options.defaultVal) {
                            var textCon = textTruncation(options.data[i].data[j][1]);
                            $("#" + id).val(textCon);
                            break;
                        }
                    }

                }
                $("#searchSelect-hidden-" + id).val(options.defaultVal);
            } else if (options.selectFirst) {
                $("#" + id).val(options.data[0].data[0][1]);
                $("#searchSelect-hidden-" + id).val(options.data[0].data[0][0]);
            }
        }
        init();

        var LiBindClick = function () {
            $("#searchSelect-UL-" + id + " li").click(function () {
                var liVal = $(this).attr("val");
                var liText = $(this).html();
                $("#" + id).val(liText);
                $("#" + id).attr("title", liText);
                $("#searchSelect-UL-" + id).slideUp();
                //if ($("#searchSelect-hidden-" + id).val() != liVal) {
                $("#searchSelect-hidden-" + id).val(liVal);
                $("#searchSelect-UL-" + id).slideUp();
                options.onChange(liVal);
                //}
            });
        }

        $("#" + id + ", #" + options.selectBtnId).click(function () {
            if (options.data && options.data.length <= 0) return;

            $("#" + id).val("");
            $("#" + id).attr("title", "");
            $("#" + id).css("cursor", "text");
            $("#" + id).focus();
            var curVal = $("#searchSelect-hidden-" + id).val();
            if (curVal == "" && options.selectFirst) {
                curVal = options.data[0].data[0][0];
                $("#searchSelect-hidden-" + id).val(curVal);
            }


            var leftpx = thisobj.offset().left; //当前对象的距离左边距离
            var toppx = thisobj.offset().top; 	//当前对象的距离顶部距离
            $("#searchSelect-UL-" + id).css("left", leftpx);
            $("#searchSelect-UL-" + id).css("top", toppx + height + 3);

            var htmlLi = "";
            var curNum = 0;
            var optGroupNum = 0;
            for (var i = 0, l = options.data.length; i < l; ++i) {
                htmlLi += '<span style="height:' + options.groupHeight + 'px; line-height:' + options.groupLineHeight + 'px;">' + options.data[i].optgroup + '</span>';
                for (var j = 0, len = options.data[i].data.length; j < len; ++j) {
                    var textCon = textTruncation(options.data[i].data[j][1]);
                    var curClass = "";
                    if (options.data[i].data[j][0] == curVal) {
                        curClass = ' class="cur"';
                        optGroupNum = i + 1;
                        curNum = j + 1;
                    }
                    htmlLi += '<li' + curClass + ' title="' + options.data[i].data[j][1] + '" val="' + options.data[i].data[j][0] + '" style="height:' + options.liHeight + 'px; line-height:' + options.liHeight + 'px;">' + textCon + '</li>';
                }
            }
            $("#searchSelect-UL-" + id).html(htmlLi);

            LiBindClick();
            $("#searchSelect-UL-" + id).slideDown();
            if (curNum > 0) {
                var otherCurNum = 0;
                for (var i = 0; i < optGroupNum - 1; ++i) {
                    otherCurNum += options.data[i].data.length;
                }
                var ulScrollTop = (curNum + otherCurNum) * options.liHeight - options.ulmaxheight + optGroupNum * options.groupHeight;
                $("#searchSelect-UL-" + id).get(0).scrollTop = ulScrollTop;
            }
        });

        var eventfunc = doAdd();
        eventfunc(document, 'mousedown', function (event) {
            if (!event) {
                event = window.event;
            }
            var tmpId = "searchSelect-UL-" + id;
            var el = $(event.srcElement || event.target);
            if (el[0].id != tmpId && el.parents('#' + tmpId).length == 0 && el[0] != $("#" + id).get(0) && el[0] != $("#" + options.selectBtnId).get(0)) {
                var curVal = $("#searchSelect-hidden-" + id).val();
                var flag = true;
                for (var i = 0, l = options.data.length; i < l; ++i) {
                    for (var j = 0, len = options.data[i].data.length; j < len; ++j) {
                        if (curVal == options.data[i].data[j][0]) {
                            $("#" + id).val(options.data[i].data[j][1]);
                            $("#" + id).attr("title", options.data[i].data[j][1]);
                            flag = false;
                            break;
                        }
                    }

                }
                if (flag) $("#" + id).val(options.defaultText);
                $("#searchSelect-UL-" + id).slideUp();
                $("#" + id).css("cursor", "default");
            }
        }, false);

        thisobj.keyup(function (e) {
            //if(e.keyCode != 8 && (e.keyCode < 48 || e.keyCode > 90)) return;
            var searchTxt = thisobj.val();
            var searchLi = new Array();
            for (var i = 0, l = options.data.length; i < l; ++i) {
                searchLi[i] = "";
                for (var j = 0, len = options.data[i].data.length; j < len; ++j) {
                    if (options.data[i].data[j][1].toUpperCase().indexOf(searchTxt.toUpperCase()) >= 0) {
                        var textCon = textTruncation(options.data[i].data[j][1]);
                        searchLi[i] += '<li title="' + options.data[i].data[j][1] + '" val="' + options.data[i].data[j][0] + '">' + textCon + '</li>';
                    }
                }
                if (searchLi[i] != "") searchLi[i] = '<span style="height:' + options.groupHeight + 'px; line-height:' + options.groupLineHeight + 'px;">' + options.data[i].optgroup + '</span>' + searchLi[i];
            }


            $("#searchSelect-UL-" + id).html(searchLi.join(""));
            if (searchLi == "") {
                $("#searchSelect-UL-" + id).css("display", "none");
            } else {
                $("#searchSelect-UL-" + id).css("display", "block");
            }
            LiBindClick();

            /*if(e.keyCode == 38){
            for(var i = 0, l = $("#searchSelect-UL-" + id + " li").length; i < l; ++i){
            if($("#searchSelect-UL-" + id + " li").eq(i).attr("class") == "cur" && i != 0){
            $("#searchSelect-UL-" + id + " li").eq(i).removeClass("cur");
            $("#searchSelect-UL-" + id + " li").eq(i - 1).addClass("cur");
            break;
            }
            }
            }else if(e.keyCode == 40){
            for(var i = 0, l = $("#searchSelect-UL-" + id + " li").length; i < l; ++i){
            if(i == 0) alert($("#searchSelect-UL-" + id + " li").eq(i).attr("class"));
            if($("#searchSelect-UL-" + id + " li").eq(i).attr("class") == "cur" && i != l){
            $("#searchSelect-UL-" + id + " li").eq(i).removeClass("cur");
            $("#searchSelect-UL-" + id + " li").eq(i + 1).addClass("cur");
            break;
            }
            }
            }
            */
        });

    }
});
function doAdd() {
    if (window.addEventListener) {
        return function (el, eventName, fn, capture) {
            el.addEventListener(eventName, fn, (capture));
        };
    } else if (window.attachEvent) {
        return function (el, eventName, fn, capture) {
            el.attachEvent("on" + eventName, fn);
        };
    } else {
        return function () {
        };
    }
}

function mousedown(event) {

}


function GetStrLength(str) {
    ///<summary>获得字符串实际长度，中文2，英文1</summary>
    ///<param name="str">要获得长度的字符串</param>
    var realLength = 0, len = str.length, charCode = -1;
    for (var i = 0; i < len; i++) {
        charCode = str.charCodeAt(i);
        if (charCode >= 0 && charCode <= 128) realLength += 1;
        else realLength += 2;
    }
    return realLength;
};

function SetStrLength(str, len) {
    var strlen = 0;
    var s = "";
    for (var i = 0; i < str.length; i++) {
        if (str.charCodeAt(i) > 128) {
            strlen += 2;
        } else {
            strlen++;
        }
        s += str.charAt(i);
        if (strlen >= len) {
            return s;
        }
    }
    return s;
}